{/* Copyright 2025 Adobe. All rights reserved.
This file is licensed to you under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License. */}

import {Layout} from '../../src/Layout';
export default Layout;
import {GroupedPropTable} from '../../src/PropTable';
import {FunctionAPI} from '../../src/FunctionAPI';
import docs from 'docs:@react-aria/focus';

export const section = 'Interactions';
export const description = 'Manages focus within a group of elements, supporting features like focus containment and restoration.';

# FocusScope

<PageDescription>{docs.exports.FocusScope.description}</PageDescription>

## Introduction

`FocusScope` is a utility component that can be used to manage focus for its descendants.
When the `contain` prop is set, focus is contained within the scope. This is useful when
implementing overlays like modal dialogs, which should not allow focus to escape them while open.
In addition, the `restoreFocus` prop can be used to restore focus back to the previously focused
element when the focus scope unmounts, for example, back to a button which opened a dialog.
A FocusScope can also optionally auto focus the first focusable element within it on mount
when the `autoFocus` prop is set.

The <TypeLink links={docs.links} type={docs.exports.useFocusManager} /> hook can also be used
in combination with a FocusScope to programmatically move focus within the scope. For example,
arrow key navigation could be implemented by handling keyboard events and using a focus manager
to move focus to the next and previous elements.

## Example

A basic example of a focus scope that contains focus within it is below. Clicking the "Open"
button mounts a FocusScope, which auto focuses the first input inside it. Once open, you can
press the <Keyboard>Tab</Keyboard> key to move within the scope, but focus is contained inside. Clicking the "Close"
button unmounts the focus scope, which restores focus back to the button.

For a full example of building a modal dialog, see [useDialog](Modal/useDialog.html).

```tsx render
'use client';
import React from 'react';
import {FocusScope} from '@react-aria/focus';

function Example() {
  let [isOpen, setOpen] = React.useState(false);
  return (
    <>
      <button onClick={() => setOpen(true)}>Open</button>
      {isOpen &&
        <FocusScope contain restoreFocus autoFocus>
          <label htmlFor="first-input">First Input</label>
          <input id="first-input" />
          <label htmlFor="second-input">Second Input</label>
          <input id="second-input" />
          <button onClick={() => setOpen(false)}>Close</button>
        </FocusScope>
      }
    </>
  );
}
```

## useFocusManager Example

This example shows how to use `useFocusManager` to programmatically move focus within a
`FocusScope`. It implements a basic toolbar component, which allows using the left and
right arrow keys to move focus to the previous and next buttons. The `wrap` option is
used to make focus wrap around when it reaches the first or last button.

```tsx render
'use client';
import {FocusScope} from '@react-aria/focus';
import {useFocusManager} from '@react-aria/focus';

function Toolbar(props) {
  return (
    <div role="toolbar">
      <FocusScope>
        {props.children}
      </FocusScope>
    </div>
  );
}

function ToolbarButton(props) {
  let focusManager = useFocusManager();
  let onKeyDown = (e) => {
    switch (e.key) {
      case 'ArrowRight':
        focusManager.focusNext({wrap: true});
        break;
      case 'ArrowLeft':
        focusManager.focusPrevious({wrap: true});
        break;
    }
  };

  return (
    <button
      onKeyDown={onKeyDown}>
      {props.children}
    </button>
  );
}

<Toolbar>
  <ToolbarButton>Cut</ToolbarButton>
  <ToolbarButton>Copy</ToolbarButton>
  <ToolbarButton>Paste</ToolbarButton>
</Toolbar>
```

## API

### FocusScope

<PropTable links={docs.links} component={docs.exports.FocusScope} />

### FocusManager Interface

To get a focus manager, call the <TypeLink links={docs.links} type={docs.exports.useFocusManager} /> hook
from a component within the FocusScope. A focus manager supports the following methods:

<ClassAPI links={docs.links} class={docs.exports.FocusManager} />